﻿Public Class GlyphEditingArea

    Public Shared ReadOnly ZoomProperty As DependencyProperty = _
        DependencyProperty.Register( _
            "Zoom", GetType(Double), GetType(GlyphEditingArea), _
            New FrameworkPropertyMetadata(1.0#))

    Public Shared ReadOnly RotationProperty As DependencyProperty = _
        DependencyProperty.Register( _
            "Rotation", GetType(Double), GetType(GlyphEditingArea), _
            New FrameworkPropertyMetadata(0.0#))

    Public Shared ReadOnly DrawingAttributesProperty As DependencyProperty = _
        DependencyProperty.Register( _
            "DrawingAttributes", GetType(DrawingAttributes), GetType(GlyphEditingArea), _
            New FrameworkPropertyMetadata(New DrawingAttributes))



    Public Property Zoom As Double
        Get
            Return CType(GetValue(ZoomProperty), Double)
        End Get
        Set(ByVal value As Double)
            SetValue(ZoomProperty, value)
        End Set
    End Property

    Public Property Rotation As Double
        Get
            Return CType(GetValue(RotationProperty), Double)
        End Get
        Set(ByVal value As Double)
            SetValue(RotationProperty, value)
        End Set
    End Property

    Public Property DrawingAttributes As DrawingAttributes
        Get
            Return CType(GetValue(DrawingAttributesProperty), DrawingAttributes)
        End Get
        Set(ByVal value As DrawingAttributes)
            SetValue(DrawingAttributesProperty, value)
        End Set
    End Property



    Private undoRedoStack As New UndoRedoStack

    Public Sub New()
        InitializeComponent()

        If DesignerProperties.GetIsInDesignMode(Me) Then
            Panel.SetZIndex(Me, -1)
        End If

        AddHandler canvas.StrokeCollected, Sub(sender, e) undoRedoStack.EnqueueStrokesChanged(canvas.Strokes, {e.Stroke}, {})
        AddHandler canvas.StrokeErasing, Sub(sender, e) undoRedoStack.EnqueueStrokesChanged(canvas.Strokes, {}, {e.Stroke})
        AddHandler canvas.StrokesReplaced, Sub(sender, e) undoRedoStack.EnqueueStrokesChanged(canvas.Strokes, e.NewStrokes, e.PreviousStrokes)
        AddHandler canvas.SelectionMoving, AddressOf OnStrokesTransformed
        AddHandler canvas.SelectionResizing, AddressOf OnStrokesTransformed
    End Sub

    Private Sub OnStrokesTransformed(sender As Object, e As InkCanvasSelectionEditingEventArgs)
        undoRedoStack.EnqueueStrokesTransformed(canvas.Strokes, e.NewRectangle, e.OldRectangle, canvas.GetSelectedStrokes)
    End Sub



    Private Sub UndoCommand_CanExecute(sender As Object, e As CanExecuteRoutedEventArgs)
        e.CanExecute = undoRedoStack.CanUndo
    End Sub

    Private Sub UndoCommand_Executed(sender As Object, e As ExecutedRoutedEventArgs)
        undoRedoStack.Undo()
    End Sub

    Private Sub RedoCommand_CanExecute(sender As Object, e As CanExecuteRoutedEventArgs)
        e.CanExecute = undoRedoStack.CanRedo
    End Sub

    Private Sub RedoCommand_Executed(sender As Object, e As ExecutedRoutedEventArgs)
        undoRedoStack.Redo()
    End Sub

    Private Sub ClearCommand_CanExecute(sender As Object, e As CanExecuteRoutedEventArgs)
        If canvas IsNot Nothing Then
            e.CanExecute = canvas.Strokes.Count > 0
        End If
    End Sub

    Private Sub ClearCommand_Executed(sender As Object, e As ExecutedRoutedEventArgs)
        canvas.Strokes.Clear()
    End Sub

    Private Sub ChangeEditModeCommand_CanExecute(sender As Object, e As CanExecuteRoutedEventArgs)
        e.CanExecute = True
    End Sub

    Private Sub ChangeEditModeCommand_Executed(sender As Object, e As ExecutedRoutedEventArgs)
        canvas.EditingMode = CType(e.Parameter, InkCanvasEditingMode)
    End Sub

End Class


Public Class ParamEqualityConverter
    Implements IValueConverter

    Public Shared Instance As New ParamEqualityConverter

    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.Convert
        Return value.Equals(parameter)
    End Function

    Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException
    End Function
End Class

